package com.briup.bookstore.common.security;

import com.briup.bookstore.domain.bean.User;

/**
 * 认证上下文内容，用于维护在登录认证拦截器中校验过的当前登录用户，
 * 将其放到本上下文中；以便在后续的请求业务处理中使用该用户的数据，
 * 就可以不用在数据库中重复查找该用户的数据
 */
public class SecurityContext {
    // 维护用户数据，其是以当前线程作为 key，不同请求的线程不同，所以不同请求（不同用户）的数据是隔离的
    private static final ThreadLocal<User> THREAD_LOCAL = new ThreadLocal<>();

    /**
     * 获取当前线程指向的用户数据，即当前登录的用户
     *
     * @return 当前登录用户的数据
     */
    public static User currentUser() {
        return THREAD_LOCAL.get();
    }

    public static Integer userId() {
        return currentUser().getId();
    }

    /**
     * 在ThreadLocal中存入当前登录用户的数据
     *
     * @param user 当前登录用户的数据
     */
    public static void setCurrentUser(User user) {
        THREAD_LOCAL.set(user);
    }


    /**
     * ThreadLocal中由于key是当前执行任务的线程，而线程在执行完本次请求后，大概率会被回收，
     * 而ThreadLocal的value数据是弱引用的，当key不存在后，那么value对象就会在JVM堆区中越积越多，
     * 最终可能导致JVM内存溢出；
     * 所以对于ThreadLocal中的数据应该及时清理
     */
    public static void clear() {
        THREAD_LOCAL.remove();
    }
}
